package thread;

/**
 * @author SWJ
 * @create 2021-06-24 10:32
 * 本类测试单例测试模式懒汉式
 */
public class Singleton2 {
    public static void main(String[] args) {
        MySingletin2 s1 = MySingletin2.getSingletin2();
        MySingletin2 s2 = MySingletin2.getSingletin2();
        System.out.println(s1 == s2);
        //==比较的是地址值
        System.out.println(s1);
        System.out.println(s2);
        /*thread.MySingletin2@4554617c
            thread.MySingletin2@4554617c*/

    }
}

/**
 * 问题：程序中有共享资源single2,并且有多条(3句)语句操作了共享资源
 * 所以single2在多线程环境下是会有数据安全隐患的
 * 解决方案1：同步代码块【加锁，范围是操作共享资源的所有代码】
 * 解决方案2：同步方法
 * 【如果一个方法中的所有代码均需要被同步，那我们可以把这个方法设置为同步方法】
 * 注意事项：锁对象在静态方法中不能设置成this,因为静态资源优先与对象进行加载
 * 锁对象可以使用外部创建好的唯一的锁对象o但注意o也需要设置为静态哦
 * 因为静态只能调用静态
 */
class MySingletin2 {
    //私有化构造方法 为了防止外界创建调用本方法调用对象
    private MySingletin2() {
    }

    //在内部类先定义一个对象类型的引用类型变量
    static private MySingletin2 singletin2;
    //创建同步代码块中唯一的锁对象
    static Object o = new Object();

    //创建公共的全局对象访问点
    synchronized static public MySingletin2 getSingletin2() {
        if (singletin2 == null) {
            synchronized (o) {
                if (singletin2 == null) {
                    //引用类型变量还是默认值，没有创建过对象
                }
                //引用类型变量还是默认值没有创建过对象
                //singletin2是保存的当前变量地址值
                singletin2 = new MySingletin2();
            }
        }
        /**运用get方法获取Singletin2数值 创建好的本类对象的返回值
         * 如果不去if判断说明之前已经创建过对象，直接返回singletin2即可*/
        //4.将本类对象返回
        return singletin2;
    }
}

